package shaka.db.internal;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.ServiceLoader;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import shaka.db.provider.IConnectionProvider;
import shaka.db.provider.IProxoolProvider1;
import shaka.db.provider.IProxoolProvider2;
import shaka.db.provider.ISqliteProvider;

public class ConnectionManager {
	private static final ConnectionManager instance = new ConnectionManager();
	private Log log = LogFactory.getLog(ConnectionManager.class);
	private Map<String, IConnectionProvider> map;
	private IConnectionProvider defaultProvider;

	private ConnectionManager() {
		map = new LinkedHashMap<String, IConnectionProvider>();
		String alias;
		for (IConnectionProvider provider : ServiceLoader.load(IConnectionProvider.class)) {
			alias = provider.getAlias();
			if (log.isDebugEnabled()) log.debug(String.format("%s:[%s] %n", alias, provider));
			map.put(alias, provider);
			if (defaultProvider == null || "default".equals(alias)) defaultProvider = provider;
		}
		IConnectionProvider p;
		for (IProxoolProvider1 provider : ServiceLoader.load(IProxoolProvider1.class)) {
			p = new ProxoolContainer1(provider);
			alias = p.getAlias();
			if (log.isDebugEnabled()) log.debug(String.format("%s:[%s] %n", alias, p));

			map.put(alias, p);
			if (defaultProvider == null || "default".equals(alias)) defaultProvider = p;
		}
		for (IProxoolProvider2 provider : ServiceLoader.load(IProxoolProvider2.class)) {
			p = new ProxoolContainer2(provider);
			alias = p.getAlias();
			if (log.isDebugEnabled()) log.debug(String.format("%s:[%s] %n", alias, p));

			map.put(alias, p);
			if (defaultProvider == null || "default".equals(alias)) defaultProvider = p;
		}
		for (ISqliteProvider provider : ServiceLoader.load(ISqliteProvider.class)) {
			p = new SqliteContainer(provider);
			alias = p.getAlias();
			if (log.isDebugEnabled()) log.debug(String.format("%s:[%s] %n", alias, p));

			map.put(alias, p);
			if (defaultProvider == null || "default".equals(alias)) defaultProvider = p;
		}
	}

	public static ConnectionManager getInstance() {
		return instance;
	}

	public Connection getConnection() throws SQLException {
		return defaultProvider.getConnection();
	}

	public Connection getConnection(String name) throws SQLException {
		return map.get(name).getConnection();
	}
}
